package com.gbase8c.dmt.dao.file;

import com.gbase8c.dmt.common.util.JsonMapper;
import com.gbase8c.dmt.dao.Dao;
import com.google.common.collect.Lists;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.lang.reflect.ParameterizedType;
import java.util.Collection;
import java.util.List;
import java.util.UUID;

public abstract class BasicDao<T> implements Dao<T> {

    protected Class<? extends T> clazz;

    public BasicDao() {
        ParameterizedType pt = (ParameterizedType) getClass().getGenericSuperclass();
        this.clazz = (Class<T>) pt.getActualTypeArguments()[0];
    }

    public abstract String path();

    protected File file(String id) {
        String filepath = StringUtils.join(new String[] {path(), id + ".json"}, File.separator);
        return new File(filepath);
    }

    public abstract File file(T t);

    public T get(String id) {
        JsonMapper jsonMapper = JsonMapper.nonEmptyMapper();
        T t = jsonMapper.fromFile(file(id), clazz);
        return t;
    }

    public List<T> list() {
        List<T> ts = Lists.newArrayList();
        File path = new File(path());
        Collection<File> files = FileUtils.listFiles(path, new String[] {"json"}, true);

        for (File file : files) {
            JsonMapper jsonMapper = JsonMapper.nonEmptyMapper();
            T t = jsonMapper.fromFile(file, clazz);
            if (ObjectUtils.isNotEmpty(t)) {
                ts.add(t);
            }
        }
        return ts;
    }

    public void delete(String id) {
        File jsonFile = file(id);
        if (jsonFile.exists() && jsonFile.isFile()) {
            jsonFile.delete();
        }
    }

    public abstract void preSave(String id, T t);

    public T save(T t) {
        String id = UUID.randomUUID().toString().toLowerCase().toLowerCase().replaceAll("-", "");
        preSave(id, t);
        JsonMapper jsonMapper = JsonMapper.nonEmptyMapper();
        jsonMapper.toFile(file(t), t);
        return t;
    }

    public void update(T t) {
        JsonMapper jsonMapper = JsonMapper.nonEmptyMapper();
        jsonMapper.toFile(file(t), t);
    }

    protected void mkdirs(String path) {
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
    }

}
